package com.ddf.controller;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.ddf.entity.User;

/**sessionAttributes中，需要在类上使用sessionAttributes注解
* value 对应要放入Model中数据的Key,type代表着一类中的所有的model中的数据
*/
@SessionAttributes(value = {"user"})
@Controller
@RequestMapping("/modelAndViewDemo")
public class ModelAndViewDemo {
	private Logger log = (Logger) LoggerFactory.getLogger(this.getClass());
	private static final String SUCCESS = "success";
	
	
	/**
	 * 放入requestAttribute
	 * ModelAndView里的model数据默认都是放在requestAttributes中的，如果需要放到
	 * sessionAttributes中，需要在类上使用sessionAttributes注解
	 * value 对应要放入Model中数据的Key,type代表着一类中的所有的model中的数据
	 * @param num1
	 * @param num2
	 * @return
	 */
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView(User user) {
		ModelAndView mc = new ModelAndView();
		mc.setViewName(SUCCESS);
		mc.addObject("user", user);
		return mc;
	}
	
	/**
	 * 放入requestAttribute
	 * 采用ViewAndMap的方式返回数据，return的字符串对应了View.map参数对应这Model里的数据,SpringMVC
	 * 会自动把Map中的数据放入到request作用域中
	 * @param map
	 * @return
	 */
	@RequestMapping("/testViewAndMap")
	public String testViewAndMap(Map<String, String> map, @RequestParam String userName,
			@RequestParam(required = false) Integer age) {
		// map里的数据会放入到Model中
		map.put("userName", userName);
		map.put("age", age.toString());
		// this is a view
		return SUCCESS;
	}
	
	
	/**
	 * 传参失败抛出异常，直接在代码中赋值可以
	 * 补充： 失败的原因是传参时指定的参数为User user，
	 * 确定了入参的对象的Key为user,SpringMVC在其封装的用于存储request作用域的对象中查找key为user
	 * 对应的对象来入参，但是没有找到，之后SpringMVC会检查当前handler是否使用了@SessionAttributes
	 * 注解，并且注解中的value值包含了当前入参的key，对应过后会在HttpSession中根据Key查找对象，找不到
	 * 则抛出异常。
	 * 解决方法，在使用了@SessionAttributes的handler中的入参的方法使用@ModelAndAttributes指定
	 * 和@SessionAttributes中的value属性不一致。
	 * 如下，使用了@ModelAttribute("us")，则HttpSession从ModelAndView中获取到user对应的对象放入到
	 * HttpSession中，同时ModelAttribute注解会把对应以key为us的对象存放到implictModel中，所以页面中
	 * 以us对应的key也能获取到user对象
	 * @return
	 */
	@RequestMapping("/testSessionAttributes")
	public ModelAndView testSessionAttributes(@ModelAttribute("us") User user) {
		log.info("testSessionAttributes");
		// 不传参的情况
		/*User user = new User();
		user.setUserName("dingdongfang");
		user.setSex("nan");
		user.setEmail("1041765757@qq.com");
		Address address = new Address();
		address.setProvince("SH");
		address.setCity("shanghai");
		user.setAddress(address);*/
		ModelAndView mc = new ModelAndView();
		mc.setViewName(SUCCESS);
		mc.addObject("user", user);
		return mc;
	}
	
	/**
	 * 测试自定义视图解析器，根据返回值对应beanName来寻找视图解析器
	 * @return
	 */
	@RequestMapping("/testXmlView")
	public String testXmlView(User user) {
		return "xmlViewDemo";
	}
}
